package org.bwapi.bridge.model;

import java.util.Set;

import org.apache.commons.collections15.Transformer;
import org.bwapi.bridge.swig.RaceSet;
import org.bwapi.bridge.swig.RaceSetIterator;
import org.bwapi.bridge.swig.SWIGTYPE_p_Race;
import org.bwapi.bridge.swig.SWIGTYPE_p_std__setT_BWAPI__Race_t;
import org.bwapi.bridge.swig.bridge;
import org.cretz.swig.collection.NativeSet;
import org.cretz.swig.util.SwigUtils;


/**
 * Race
 * 
 * @see <a href="http://code.google.com/p/bwapi/wiki/Race">Race</a>
 * 
 * @author Chad Retz
 */
public class Race extends BwapiComparable<Race> {
	private static final Transformer<Race, org.bwapi.bridge.swig.Race> FROM = 
		new Transformer<Race, org.bwapi.bridge.swig.Race>() {
			@Override
			public org.bwapi.bridge.swig.Race transform(Race race) {
				return race.getRace();
			}
		};
		
	private static final Transformer<org.bwapi.bridge.swig.Race, Race> TO = 
		new Transformer<org.bwapi.bridge.swig.Race, Race>() {
			@Override
			public Race transform(org.bwapi.bridge.swig.Race race) {
				return new Race(race);
			}
		};

	public static final Race ZERG = new Race(bridge.getZerg());
	public static final Race TERRAN = new Race(bridge.getTerran());
	public static final Race PROTOSS = new Race(bridge.getProtoss());
	public static final Race RANDOM = new Race(bridge.getRandom());
	public static final Race OTHER = new Race(bridge.getOther());
	public static final Race NONE = new Race(bridge.getRaceNone());
	public static final Race UNKNOWN = new Race(bridge.getRaceUnknown());
	
	public static Set<Race> allRaces() {
		return newSet(bridge.allRaces());
	}
	
	static Set<Race> newSet(SWIGTYPE_p_std__setT_BWAPI__Race_t nativeSet) {
		return new NativeSet<Race, org.bwapi.bridge.swig.Race>(
				org.bwapi.bridge.swig.Race.class, RaceSetIterator.class, 
				nativeSet, RaceSet.class, FROM, TO);
	}
	
	/**
	 * Not implemented
	 * 
	 * @param name
	 * @return
	 * 
	 * @deprecated Not implemented
	 */
	@Deprecated
	public static Race getRace(String name) {
		throw new UnsupportedOperationException();
	}
	
	private final org.bwapi.bridge.swig.Race race;
	
	Race(org.bwapi.bridge.swig.Race race) {
		this.race = race;
	}
	
	Race(SWIGTYPE_p_Race pointer) {
		this(SwigUtils.getSwigPointer(SwigUtils.getSwigPointer(pointer), 
				false, org.bwapi.bridge.swig.Race.class));
	}

	public Race() {
		this(new org.bwapi.bridge.swig.Race());
	}

	public Race(int id) {
		this(new org.bwapi.bridge.swig.Race(id));
	}

	public Race(Race other) {
		this(new org.bwapi.bridge.swig.Race(other.getRace()));
	}
	
	org.bwapi.bridge.swig.Race getRace() {
		return race;
	}
	
	SWIGTYPE_p_Race getPointer() {
		return SwigUtils.getSwigPointer(race, SWIGTYPE_p_Race.class);
	}

	@Override
	public Race opAssign(Race other) {
		return new Race(race.opAssign(other.getRace()));
	}

	@Override
	public boolean opEquals(Race other) {
		return race.opEquals(other.getRace());
	}

	@Override
	public boolean opNotEquals(Race other) {
		return race.opNotEquals(other.getRace());
	}

	@Override
	public boolean opLessThan(Race other) {
		return race.opLessThan(other.getRace());
	}

	@Override
	public int getID() {
		return race.getID();
	}

	public String getName() {
		return race.getName();
	}

	public UnitType getWorker() {
		org.bwapi.bridge.swig.UnitType worker = race.getWorker();
		return worker == null ? null : new UnitType(worker);
	}

	public UnitType getCenter() {
		org.bwapi.bridge.swig.UnitType center = race.getCenter();
		return center == null ? null : new UnitType(center);
	}

	public UnitType getRefinery() {
		org.bwapi.bridge.swig.UnitType refinery = race.getRefinery();
		return refinery == null ? null : new UnitType(refinery);
	}

	public UnitType getTransport() {
		org.bwapi.bridge.swig.UnitType transport = race.getTransport();
		return transport == null ? null : new UnitType(transport);
	}

	public UnitType getSupplyProvider() {
		org.bwapi.bridge.swig.UnitType provider = race.getSupplyProvider();
		return provider == null ? null : new UnitType(provider);
	}
}
